(function($) {
    /**
     * 单页固定导航
     * @param  {int} startOffset 需要修正的滚动监听高度差，在需要监听的目标上方有动态变为fixed的元素时使用
     * @return {[type]}        [description]
     */
    $.fn.fixed = function(option) {
        return this.each(function() {
            var opt = $.extend({}, {
                navItemSelector : "li",
                activeClass     : "active",
                sticky          : false, // 是否启用position:sticky
                singleNav       : true, // 是否启用单页导航效果
                enableClick     : true, // 是否允许导航项目点击跳转事件
                infiScroll      : true // 是否限制最大滚动高度，适用于导航仅在某个范围内滚动
            }, option || {});

            var $nav        = $(this);
            var $navItems   = $nav.find(opt.navItemSelector);
            var $fixedNav   = $nav.clone().attr("id", $nav.attr("id")+"-clone").css({"display": "none", "visibility": "hidden"}).insertAfter($nav);
            var startOffset = opt.startOffset === undefined ? $nav.height() : opt.startOffset;
            var n           = $navItems.length;
            var left        = opt.left || $nav.offset().left || 0;
            var top         = opt.top || 0;
            var isSticky    = isSupportSticky();
            var offsets     = resetOffset();
            var maxScrollTop = opt.infiScroll ? 999999 : offsets[n-1] - startOffset + $($navItems.eq(n-1).data("target")).height() - $nav.height();

            opt.sticky = isSticky && opt.sticky;

            $navItems.on("click", function() {
                offsets = resetOffset();
                if (opt.enableClick) {
                    $(window).scrollTop(offsets[$(this).index()] - startOffset + 1);
                    $(this).addClass("active").siblings().removeClass("active");
                } else {
                    $(window).scrollTop($fixedNav.offset().top);
                }
            });

            $nav.toggleClass("sticky", opt.sticky);
            if (offsets[0] == 0) return;

            $(window).on("scroll touchmove", scrollHandler);

            // 重新计算各模块的起始点，避免异步加载的模块影响高度计算
            function resetOffset() {
                return $navItems.map(function() {
                    return $($(this).data("target")).offset().top;
                }).get();
            }

            function scrollHandler() {
                offsets = resetOffset();
                var scrolltop = $(window).scrollTop();
                if (opt.singleNav) singleNav(scrolltop);
                if (opt.sticky) return;

                if (scrolltop >= offsets[0] - startOffset && scrolltop < maxScrollTop) {
                    setNavPosition();
                } else {
                    restore();
                }
            }

            // 单页导航
            function singleNav(scrolltop) {
                offsets = resetOffset();
                $.each(offsets, function(i, v) {
                    if (scrolltop >= v - startOffset) {
                        $navItems.removeClass(opt.activeClass).eq(i).addClass(opt.activeClass);
                    }
                });
            }

            function resizeHandler() {
                if ($nav.hasClass("fixed")) {
                    left = opt.left || $fixedNav.css("visibility", "visible").offset().left || 0;
                    $fixedNav.css("visibility", "hidden");
                    setNavPosition();
                } else {
                    left = opt.left || $nav.offset().left || 0;
                }
            }

            function setNavPosition() {
                $nav.addClass("fixed").css({
                    "z-index": 999,
                    "left": left,
                    "top": top
                });
                $fixedNav.css({"display": "block"});
            }

            function restore() {
                $fixedNav.css({"display": "none"});
                $nav.removeClass("fixed").removeAttr("style");
            }

            // 判断是否支持sticky属性
            function isSupportSticky() {
                var prefixTestList = ['', '-webkit-', '-ms-', '-moz-', '-o-'];
                var stickyText = '';
                for (var i = 0; i < prefixTestList.length; i++ ) {
                    stickyText += 'position:' + prefixTestList[i] + 'sticky;';
                }
                // 创建一个dom来检查
                var div = document.createElement('div');
                var body = document.body;
                div.style.cssText = 'display:none;' + stickyText;
                body.appendChild(div);
                var isSupport = /sticky/i.test(window.getComputedStyle(div).position);
                body.removeChild(div);
                div = null;
                return isSupport;
            }

            scrollHandler(); // 部分浏览器有记忆机制，故页面加载时先执行一次方法
        });
    };
})(Zepto);
